<?php

class MidiasBehavior extends ModelBehavior {

    public $settings = array(
        'path' => 'img/uploads',
        'extensions' => array('jpg', 'png', 'bmp', 'gif', 'jpeg', 'jpe', 'pdf'),
        'max_width' => 0,
        'max_height' => 0,
        'name' => '',
        'subistituir' => FALSE,
        'size' => 0, // in KB (Ko)
        'input' => 'file', // nome do input que faz o upload
        'tipo' => 'file', // tipo (url or $_file)
    );
    private $uploadError = NULL;

    public function setup(Model $model, $config = array()) {
        $this->settings = Hash::merge($this->settings, $config);
    }

    public function beforeSave(Model $model, $options = array()) {
        if (isset($model->data[$model->alias][$this->settings['input']])) {
            if ($this->settings['tipo'] == 'file') {
                if (is_array($model->data[$model->alias][$this->settings['input']]['name'])) {
                    foreach ($model->data[$model->alias][$this->settings['input']]['name'] as $key => $value) {
                        $__file = array(
                            'name' => $model->data[$model->alias][$this->settings['input']]['name'][$key],
                            'type' => $model->data[$model->alias][$this->settings['input']]['type'][$key],
                            'tmp_name' => $model->data[$model->alias][$this->settings['input']]['tmp_name'][$key],
                            'error' => $model->data[$model->alias][$this->settings['input']]['error'][$key],
                            'size' => $model->data[$model->alias][$this->settings['input']]['size'][$key]
                        );
                        $this->__upload($model, $__file);
                    }
                } else {
                    $this->__upload($model, $model->data[$model->alias][$this->settings['input']]);
                }
            } else if ($this->settings['tipo'] == 'url') {
                $this->__upload_url($model, $model->data[$model->alias][$this->settings['input']]);
            }
            unset($model->data[$model->alias][$this->settings['input']]);
            if ($this->uploadError) {
                return false;
            }
        }
        return true;
    }

    public function afterSave(Model $model, $created, $options = array()) {
        $this->fileSave($model);
        return true;
    }

    public function __upload(Model $model, $file) {
        if ($this->validateUploadError($model, $file)) {
            $extension = $this->fileExtension($model, $file['name'], false);
            if (!in_array($extension, $this->settings['extensions'])) {
                $this->uploadError = __d('midias', 'Informed extension "%s" is not allowed.', $extension);
            } else {
                $name = str_replace('.' . $extension, '', $file['name']);
                if (!move_uploaded_file($file['tmp_name'], WWW_ROOT . ltrim($this->settings['path'], '/') . Inflector::underscore($name) . '.' . strtolower($extension))) {
                    $this->uploadError = __d('midias', 'Unable to copy file "%s".', $file['name']);
                } else {
                    $this->settings['name'] = Inflector::underscore($name) . '.' . strtolower($extension);
                }
            }
        }
    }

    public function uploadError() {
        return $this->uploadError;
    }

    public function __upload_url(Model $model, $file) {
        if (trim($file) != '') {
            $extension = $this->fileExtension($model, $file, false);
            if (!in_array($extension, $this->settings['extensions'])) {
                $this->uploadError = __d('midias', 'Informed extension "%s" is not allowed.', $extension);
            } else {
                $name = str_replace('.' . $extension, '', $file);
                if (!copy($file, WWW_ROOT . ltrim($this->settings['path'], '/') . Inflector::underscore($name) . '.' . strtolower($extension))) {
                    $this->uploadError = __d('midias', 'Unable to copy file "%s".', $file['name']);
                } else {
                    $this->settings['name'] = Inflector::underscore($name) . '.' . strtolower($extension);
                }
            }
        }
        return TRUE;
    }

    public function afterFind(Model $model, $results, $primary = false) {
        $midia = ClassRegistry::init('Midias.Midia');

        if (count($results)) {
            
            if (isset($results[$model->alias])) {
                $results['Midia'] = array();
                $consulta = $midia->find('all', array('conditions' => array('Midia.model' => $model->alias, 'Midia.model_id' => $results[$model->alias]['id'])));
                if (count($consulta) > 0) {
                    foreach ($consulta as $_k => $_v) {
                        $results['Midia'][$_k] = $_v['Midia'];
                    }
                } else {
                    $results['Midia'] = array();
                }
            } else {
                foreach ($results as $key => $value) {
                    foreach ($value as $k => $v) {
                        if ($k == $model->alias) {
                            $results[$key]['Midia'] = array();
                            $consulta = $midia->find('all', array('conditions' => array('Midia.model' => $model->alias, 'Midia.model_id' => $results[$key][$model->alias]['id'])));
                            if (count($consulta) > 0) {
                                foreach ($consulta as $_k => $_v) {
                                    $results[$key]['Midia'][$_k] = $_v['Midia'];
                                }
                            } else {
                                $results[$key]['Midia'] = array();
                            }
                        }
                    }
                }
            }
        }
        return $results;
    }

    public function beforeDelete(Model $model, $cascade = true) {
        $midia = ClassRegistry::init('Midias.Midia');
        $find = $midia->find('first', array('conditions' => array('Midia.model' => $model->alias, 'Midia.model_id' => $model->id)));
        if (count($find) > 0) {
            @unlink(WWW_ROOT . $find['Midia']['diretorio'] . $find['Midia']['nome']);
            $midia->delete($find['Midia']['id']);
        }
        return parent::beforeDelete($model, $cascade);
    }

    public function fileSave(Model $model) {
        if (empty($this->uploadError)) {
            if ($this->settings['name'] != '') {
                $midia = ClassRegistry::init('Midias.Midia');
                if ($this->settings['subistituir'] === TRUE) {
                    $midia->deleteAll(array('Midia.model' => $model->alias, 'Midia.model_id' => $model->id));
                }
                $midia->save(array('Midia' => array(
                        'nome' => $this->settings['name'],
                        'diretorio' => $this->settings['path'],
                        'model' => $model->alias,
                        'model_id' => $model->id
                )));
                $midia->clear();
            }
        }
        return TRUE;
    }

    /**
     * Valdates the error value that comes with the file input file
     *
     * @param Model $model
     * @param integer Error value from the form input [file_field][error]
     * @return boolean True on success, if false the error message is set to the models field and also set in $this->uploadError
     */
    public function validateUploadError(Model $model, $file = array()) {
        if (!is_null($file['error'])) {
            switch ($file['error']) {
                case UPLOAD_ERR_OK:
                    return true;
                    break;
                case UPLOAD_ERR_INI_SIZE:
                    $this->uploadError = __d('midias', 'The uploaded file exceeds limit of %s.', CakeNumber::toReadableSize(ini_get('upload_max_filesize')));
                    break;
                case UPLOAD_ERR_FORM_SIZE:
                    $this->uploadError = __d('midias', 'The uploaded file is to big, please choose a smaller file or try to compress it.');
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $this->uploadError = __d('midias', 'The uploaded file was only partially uploaded.');
                    break;
                case UPLOAD_ERR_NO_TMP_DIR:
                    $this->uploadError = __d('midias', 'The remote server has no temporary folder for file uploads. Please contact the site admin.');
                    break;
                case UPLOAD_ERR_CANT_WRITE:
                    $this->uploadError = __d('midias', 'Failed to write file to disk. Please contact the site admin.');
                    break;
                case UPLOAD_ERR_EXTENSION:
                    $this->uploadError = __d('midias', 'File upload stopped by extension. Please contact the site admin.');
                    break;
            }
            return false;
        }
        return true;
    }

    /**
     * Return file extension from a given filename
     *
     * @param Model $Model
     * @param $name
     * @param bool $realFile
     * @internal param $string
     * @return boolean string or false
     */
    public function fileExtension(Model $model, $name, $realFile = true) {
        if ($realFile) {
            return pathinfo($name, PATHINFO_EXTENSION);
        }
        return substr(strrchr($name, '.'), 1);
    }

}
